//package org.example.config;
//
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import org.example.entity.Permissions;
//import org.example.entity.Users;
//import org.example.filter.TokenFilter;
//import org.example.models.LoginUser;
//import org.example.models.R;
//import org.example.service.PermissionsService;
//import org.example.service.UsersService;
//import org.example.utils.JwtUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.http.MediaType;
//import org.springframework.security.access.AccessDeniedException;
//import org.springframework.security.authentication.BadCredentialsException;
//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.core.Authentication;
//import org.springframework.security.core.AuthenticationException;
//import org.springframework.security.core.userdetails.User;
//import org.springframework.security.core.userdetails.UserDetails;
//import org.springframework.security.core.userdetails.UserDetailsService;
//import org.springframework.security.core.userdetails.UsernameNotFoundException;
//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//import org.springframework.security.provisioning.InMemoryUserDetailsManager;
//import org.springframework.security.web.AuthenticationEntryPoint;
//import org.springframework.security.web.SecurityFilterChain;
//import org.springframework.security.web.access.AccessDeniedHandler;
//import org.springframework.security.web.authentication.AuthenticationFailureHandler;
//import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
//import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
//
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.awt.*;
//import java.io.IOException;
//import java.util.List;
//
//@Configuration
//public class SecurityConfig {
//
//    ObjectMapper objectMapper = new ObjectMapper();
//
//    @Autowired
//    UsersService usersService;
//
//    @Autowired
//    PermissionsService permissionsService;
//
//    @Autowired
//    TokenFilter tokenFilter;
//
//    @Autowired
//    RedisTemplate<String,Object> redisTemplate;
//
//    @Bean
//    public UserDetailsService userDetailsService() {
////        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
////        UserDetails user1 =
////                User.withUsername("admin")
////                        .password("{noop}admin")
////                        .authorities("user:get-user", "user:delete")
////                        .build();
////        UserDetails user2 =
////                User.withUsername("admin1")
////                        .password("{noop}admin1")
////                        .authorities("user:update-user")
////                        .build();
////        manager.createUser(user1);
////        manager.createUser(user2);
//        return new UserDetailsService() {
//            @Override
//            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//                QueryWrapper<Users> queryUser = new QueryWrapper<>();
//                queryUser.lambda().eq(Users::getUsername, username);
//                Users user = usersService.getOne(queryUser);
//                if (user == null) {
//                    throw new BadCredentialsException("用户不存在");
//                }
//                List<Permissions> permissions = permissionsService.getPermissions(user.getId());
//                LoginUser loginUser = new LoginUser(user, permissions);
//                return loginUser;
//            }
//        };
//
//    }
//
//    @Bean
//    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
//        // spring security防伪链
//        http.csrf().disable();//关闭
//        http.formLogin()
////                .loginPage("/login2") // get 登录界面
//                .loginProcessingUrl("/login")//post 登录提交的数据入口
//                .usernameParameter("username")// 修改登录的账户的参数名称
//                .passwordParameter("password") // 修改登录的密码的参数名称
//                .permitAll() // 上面两个地址不需要进行登录和权限验证
//                // 登录成功后执行的对象
//                .successHandler(new AuthenticationSuccessHandler() {
//                    @Override
//                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//                        response.setCharacterEncoding("utf-8");
//                        // 获取登录成功的认证对象
//                        LoginUser principal = (LoginUser) authentication.getPrincipal();
//                        String token = JwtUtils.generateToken(principal.getUser().getId(), principal.getUsername());
//
//                        redisTemplate.opsForValue().set(principal.getUsername(),principal);
//
//                        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
//                        R<Object> success = R.success(200, "登录成功", token);
//                        String json = objectMapper.writeValueAsString(success);
//                        response.getWriter().write(json);
//
//                    }
//                })
//                // 登录失败后执行对象
//                .failureHandler(new AuthenticationFailureHandler() {
//                    @Override
//                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
//                        response.setCharacterEncoding("utf-8");
//                        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
//                        R<Object> error = R.error(401, exception.getMessage());
//                        String json = objectMapper.writeValueAsString(error);
//                        response.getWriter().write(json);
//                    }
//                })
//        ;
//        // 设置security授权信息
//        http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
//            @Override
//            public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
//                response.setCharacterEncoding("utf-8");
//                response.setContentType(MediaType.APPLICATION_JSON_VALUE);
//                R<Object> error = R.error(403, "权限不足，请联系管理员");
//                String json = objectMapper.writeValueAsString(error);
//                response.getWriter().write(json);
//            }
//        });
//        http.authorizeHttpRequests().mvcMatchers("/index").permitAll();
////        http.sessionManagement().
////                sessionCreationPolicy(SessionCreationPolicy.NEVER)
//        // 设置需要单独验证的权限地址;
//        // 读取数据库中整个系统的所有权限列表信息
//        List<Permissions> permissions = permissionsService.list();
//        for (Permissions p : permissions) {
//            http.authorizeHttpRequests()
//                    .mvcMatchers(p.getUrl()).hasAnyAuthority(p.getPerm());
//        }
////        http.authorizeHttpRequests()
////                .antMatchers("/user/get-user").hasAuthority("user:get-user");
////        http.authorizeHttpRequests()
////                .antMatchers("/user/delete").hasAuthority("user:delete");
////        http.authorizeHttpRequests()
////                .antMatchers("/user/update-user").hasAuthority("user:update -user");
//        // 所有地址都需要登录才能访问
//        http.authorizeHttpRequests().mvcMatchers("/**").authenticated();
//        // 修改security校验顺序
//        http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);
//        return http.build();
//    }
//
//    @Bean
//    public BCryptPasswordEncoder bCryptPasswordEncoder() {
//        return new BCryptPasswordEncoder();
//    }
//}
